#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <atomic>
#include <condition_variable>

using namespace std;

// 有锁打印
void printabc()
{
    std::mutex mtx;
    std::condition_variable cond;
    int flag = 0;
    int cnt = 10;

    std::thread t1([&]() {
        for (int i = 0; i < cnt; i++) {
            std::unique_lock<std::mutex> lock(mtx);
            cond.wait(lock, [&]() { return flag == 0; });   
            std::cout << 'a';
            flag = 1;
            cond.notify_all();
        }
    });

    std::thread t2([&]() {
        for (int i = 0; i < cnt; i++) {
            std::unique_lock<std::mutex> lock(mtx);
            cond.wait(lock, [&]() { return flag == 1; });   
            std::cout << 'b';
            flag = 2;
            cond.notify_all();
        }
    });

    std::thread t3([&]() {
        for (int i = 0; i < cnt; i++) {
            std::unique_lock<std::mutex> lock(mtx);
            cond.wait(lock, [&]() { return flag == 2; });   
            std::cout << 'c' << '\n';
            flag = 0;
            cond.notify_all();
        }
    });

    t1.join();
    t2.join();
    t3.join();
}

// 无锁打印
volatile atomic<int> turn(0);

void printA(int count) 
{
	for (int i = 0; i < count; ++i) 
	{
		while (turn != 0); // 忙等
		cout << "a " << this_thread::get_id() << endl;
		turn = 1;
	}
}

void printB(int count) 
{
	for (int i = 0; i < count; ++i) 
	{
		while (turn != 1); // 忙等
		cout << "b " << this_thread::get_id() << endl;
		turn = 2;
	}
}

void printC(int count) 
{
	for (int i = 0; i < count; ++i) 
	{
		while (turn != 2); // 忙等
		cout << "c " << this_thread::get_id() << endl;
		turn = 0;
	}
}

int main()
{
    // printabc();


    int count = 10;
	thread a(printA, count);
	thread b(printB, count);
	thread c(printC, count);

	a.join();
	b.join();
	c.join();

    return 0;
}